package com.coder4j.starter.web;

import com.coder4j.starter.mybatis.BaseEntity;
import com.coder4j.starter.mybatis.BaseMapper;
import com.coder4j.starter.mybatis.BasePage;
import com.coder4j.starter.mybatis.BaseQuery;
import com.coder4j.starter.tools.util.DateUtils;
import com.coder4j.starter.tools.vo.R;
import com.coder4j.starter.web.api.ApiNote;
import com.coder4j.starter.web.util.EasyExcelUtils;
import com.coder4j.starter.web.util.ApplicationContextProvider;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

/**
 * @author keller
 * @date 2025-04-27 16:42:11
 * 基础Controller
 * @param <ENTITY> 实体类
 * @param <VO>  视图对象
 * @param <EO> Excel导出对象
 * @param <QUERY> 查询对象
 * @param <MAPPER> Mapper
 * @param <SERVICE> Service
 */
@Slf4j
@RestController
public class BaseController<ENTITY extends BaseEntity,VO,EO,
        QUERY extends BaseQuery<ENTITY>,
        MAPPER extends BaseMapper<ENTITY>,
        SERVICE extends BaseServiceImpl<MAPPER,ENTITY,VO>> {

    @Resource
    private HttpServletRequest request;

    @Resource
    private HttpServletResponse response;

    /**
     * 从 容器中取 Service
     * @return
     */
    private synchronized SERVICE getService() {
        Type genType = this.getClass().getGenericSuperclass();

        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        log.info("-------getService---{}",params[5]);
        return ApplicationContextProvider.getBean((Class<SERVICE>) params[5]);
    }

    /**
     * 反射构建 Excel导出类
     * @return
     */
    private synchronized EO initEO() {
        Type genType = this.getClass().getGenericSuperclass();
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        Class<EO> clazz = (Class<EO>) params[2];
        try {
            return clazz.newInstance();
        } catch (Exception e) {
            log.error("initEO Error",e);
        }
        return null;
    }

    /**
     * 查询详情
     * @param id
     * @return
     */
    @GetMapping("/baseGetById")
    @ApiNote(name="查询详情",createName = "keller",createTime = "2024-12-05 10:46:31")
    public R<VO> baseGetById( Long id){
        return R.success(getService().baseGetVOById(id));
    }

    @PostMapping("/baseGetDetail")
    @ApiNote(name="查询详情",createName = "keller",createTime = "2024-12-05 10:46:31")
    public R<VO> baseGetDetail(@RequestBody ENTITY entity){
        if(entity.getId() == null){
            return R.paramError();
        }
        return R.success(getService().baseGetVOById(entity.getId()));
    }


    /**
     * 保存数据
     * @param vo
     * @return
     */
    @PostMapping("/baseSave")
    @ApiNote(name="保存数据",createName = "keller",createTime = "2024-12-05 10:46:31")
    public R baseSave(@RequestBody VO vo){
        getService().baseSaveVO(vo);
        return R.success();
    }

    /**
     * 分页查询
     * @param query
     * @return
     */
    @PostMapping("/basePage")
    @ApiNote(name="分页查询",createName = "keller",createTime = "2024-12-05 10:46:31")
    public R<BasePage<VO>> basePage(@RequestBody QUERY query){
        return R.success(getService().baseQueryVOPage(query));
    }


    /**
     * 数据导出
     * @param query
     */
    @PostMapping("/baseExport")
    @ApiNote(name="数据导出",createName = "keller",createTime = "2024-12-05 10:46:31")
    public void baseExport(@RequestBody QUERY query){
        List<ENTITY> list = getService().baseQueryList(query);
                List<EO> eoList = new ArrayList<>();
                for (ENTITY entity : list) {
                    EO eo = this.initEO();
                    BeanUtils.copyProperties(entity,eo);
                    eoList.add(eo);
                }
                EasyExcelUtils.exportClass(response,"export_"+ DateUtils.getShortTimeMask(),eoList);
    }


    /**
     * 删除数据
     * @param entity
     * @return
     */
    @PostMapping("/baseDelete")
    @ApiNote(name="删除数据",createName = "keller",createTime = "2024-12-05 10:46:31")
    public R deleteById(@RequestBody ENTITY entity){
        if(entity.getId() == null){
            return R.paramError();
        }
        getService().baseDeleteById(entity.getId());
        return R.success();
    }
}
